package com.slmn.visitor.gui;

import com.slmn.visitor.gui.Component.HChild;

import javafx.geometry.Bounds;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.scene.text.Text;

public class VComposite extends Composite implements HChild {

	private final BorderPane bp = new GrowPane();
	private final VBox vbox = new VBox();
	private Text open = new Text("(");
	private Text close = new Text(")");

	public VComposite() {
		super();
		vbox.setPadding(new Insets(SPACE, 0, SPACE, 0));
		vbox.setSpacing(SPACE);
		vbox.setAlignment(Pos.CENTER);
		// vbox.setStyle("-fx-border-color: yellowgreen;");
		vbox.setOnMouseClicked(event -> {
			if (!FormulaFrame.isSelecting) {
				vbox.requestFocus();
				event.consume();
			}
		});
		vbox.focusedProperty().addListener(
				(observable, oldValue, newValue) -> {
					if (newValue == oldValue) {
						return;
					}
					if (oldValue) {
						Cursor.clearCursor();
					}
					if (newValue) {
						Cursor.setCursor(this);
					}
				});
		bp.setLeft(open);
		bp.setCenter(vbox);
		bp.setRight(close);
		BorderPane.setMargin(bp.getLeft(), new Insets(0, SPACE, 0, SPACE));
		BorderPane.setMargin(bp.getRight(), new Insets(0, SPACE, 0, SPACE));
		BorderPane.setAlignment(bp.getLeft(), Pos.CENTER);
		BorderPane.setAlignment(bp.getRight(), Pos.CENTER);
	}

	@Override
	protected final boolean isValid(Component c) {
		return c instanceof HComposite;
	};

	@Override
	public final Node getNode() {
		return bp;
	}

	@Override
	public HComposite getHParent() {
		return (HComposite) getParent();
	}

	@Override
	public Bounds getCBounds() {
		return bp.localToScene(bp.getLayoutBounds());
	}

	@Override
	public void addCursor() {
		HComposite parent = getHParent();
		if (parent != null) {
			parent.addCursor(this);
		} else {
			Cursor.prompt.setVisible(false);
			Cursor.prompt.setHeight(SPACE);
		}
	}

	@Override
	public void setCNodesBG(CNodeState state) {
		vbox.setStyle(state.getStyle());
		bp.setStyle(state.getStyle());
	}

	@Override
	protected boolean add(Component c) {
		this.children.add(c);
		return vbox.getChildren().add(c.getNode());
	}

	@Override
	protected boolean remove(Component c) {
		this.children.remove(c);
		return vbox.getChildren().remove(c.getNode());
	}

	private static class GrowPane extends BorderPane {
		GrowPane() {
			super();
		}

		@Override
		protected void layoutChildren() {
			super.layoutChildren();
			Node right = getRight();
			Node left = getLeft();
			double ratio = getHeight() / right.getLayoutBounds().getHeight();
			right.setScaleY(ratio);
			right.setScaleX(ratio / 3);
			left.setScaleY(ratio);
			left.setScaleX(ratio / 3);
		}
	}
}
